﻿using System;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using PengSW.NotifyPropertyChanged;
using PengSW.ObservableCollectionHelper;
using PengSW.XmlHelper;
using static PengSW.XmlHelper.XmlLinqHelper;

namespace ProtocolAnalyzer
{
    public class ProtocolRule : NotifyPropertyChangedObject, IXmlSeriable
    {
        public string Name { get => _Name; set { SetValue(ref _Name, value, nameof(Name)); } }
        private string _Name = "未命名规则";

        public string SendAfterConnected { get => _SendAfterConnected; set { SetValue(ref _SendAfterConnected, value, nameof(SendAfterConnected)); } }
        private string _SendAfterConnected;

        public Encoding Encoding { get => _Encoding; set { SetValue(ref _Encoding, value, nameof(Encoding)); } }
        private Encoding _Encoding = Encoding.UTF8;

        public Encoding[] Encodings => AnalyzeModel.Encodings;

        public TimeSpan ReceiveTimeOut { get => _ReceiveTimeOut; set { SetValue(ref _ReceiveTimeOut, value, nameof(ReceiveTimeOut)); } }
        private TimeSpan _ReceiveTimeOut;

        // 在发送数据时，是否需要在数据后面添加换行符
        public bool AppendNewLine { get => _AppendNewLine; set { SetValue(ref _AppendNewLine, value, nameof(AppendNewLine)); } }
        private bool _AppendNewLine = false;

        public ObservableCollectionEx<AutoResponse> AutoResponses { get; } = new ObservableCollectionEx<AutoResponse>();
        public string GetResponse(string aReceivedText)
        {
            string aResponseText = (from r in AutoResponses let t = r.GetResponse(aReceivedText) where t != null select t).FirstOrDefault();
            return aResponseText;
        }

        public ObservableCollectionEx<PreDefine> PreDefines { get; } = new ObservableCollectionEx<PreDefine>();

        public void ReadFromXml(XElement aXElement)
        {
            if (aXElement == null) return;
            Name = aXElement.GetAttributeValue(nameof(Name), "未命名规则");
            SendAfterConnected = aXElement.GetChildNodeValue(nameof(SendAfterConnected), "");
            Encoding = (from r in Encodings where r.EncodingName == aXElement.GetAttributeValue(nameof(Encoding), Encoding.UTF8.EncodingName) select r).FirstOrDefault();
            if (Encoding == null) Encoding = Encoding.UTF8;
            ReceiveTimeOut = aXElement.GetAttributeValue(nameof(ReceiveTimeOut), TimeSpan.FromSeconds(20));
            AppendNewLine = aXElement.GetAttributeValue(nameof(AppendNewLine), false);

            AutoResponses.Clear();
            foreach (XElement aChildXElement in aXElement.Element(nameof(AutoResponses))?.Elements(nameof(AutoResponse)))
            {
                AutoResponse aAutorResponse = new AutoResponse();
                aAutorResponse.ReadFromXml(aChildXElement);
                AutoResponses.Add(aAutorResponse);
            }

            PreDefines.Clear();
            foreach (XElement aChildXElement in aXElement.Element(nameof(PreDefines))?.Elements(nameof(PreDefine)))
            {
                PreDefine aPreDefine = new PreDefine();
                aPreDefine.ReadFromXml(aChildXElement);
                PreDefines.Add(aPreDefine);
            }
        }

        public XElement CreateXElement(string aXmlNodeName)
        {
            return new XElement(aXmlNodeName,
                CreateXAttribute(nameof(Name), Name),
                CreateXAttribute(nameof(Encoding), Encoding.EncodingName),
                CreateXAttribute(nameof(ReceiveTimeOut), ReceiveTimeOut),
                CreateXAttribute(nameof(AppendNewLine), AppendNewLine),
                new XElement(nameof(SendAfterConnected), SendAfterConnected),
                new XElement(nameof(AutoResponses), from r in AutoResponses select r.CreateXElement(nameof(AutoResponse))),
                new XElement(nameof(PreDefines), from r in PreDefines select r.CreateXElement(nameof(PreDefine))));
        }
    }
}
